package com.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.constant.DeviceChangeEventTypeEnum;
import com.dao.*;
import com.exception.BusinessException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.model.*;
import com.page.GenericPage;
import com.po.VenderDeviceModifyPO;
import com.po.VenderDevicePO;
import com.po.VenderDeviceQueryPO;
import com.result.Result;
import com.service.VenderDeviceService;
import com.utils.CurrentLoginUserAgent;
import com.utils.SessionUtil;
import com.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.testng.collections.Lists;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author: chihaojie
 * @Date: 2019/5/29 16:04
 * @Version 1.0
 * @Note
 */

@Slf4j
@Service
public class VenderDeviceServiceImpl implements VenderDeviceService {


    @Autowired
    private VenderDeviceMapper venderDeviceMapper;

    @Autowired
    private AdvertisementMapper advertisementMapper;

    @Autowired
    private PlacedHospitalMapper placedHospitalMapper;

    @Autowired
    private DeviceBoxMapper deviceBoxMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private DeviceChangeRecordMapper changeRecordMapper;
    @Autowired
    private AppVersionUpgradeMapper appVersionUpgradeMapper;

    @Transactional
    @Override
    public Result<VenderDeviceQueryVO> save(VenderDevicePO venderDevicePO) {
        if (StringUtils.isEmpty(venderDevicePO.getDeviceSn())) {
            return new Result<>().error("设备编号为空");
        } else if (StringUtils.isEmpty(venderDevicePO.getHospitalId())) {
            return new Result<>().error("医院ID为空");
        }
        if (StringUtils.isEmpty(venderDevicePO.getAgent())) {
            return new Result<>().error("代理商agent为空");
        }
        //判断医院是否存在
        PlacedHospital placedHospital = placedHospitalMapper.selectByPrimaryKey(venderDevicePO.getHospitalId());
        if (placedHospital == null) {
            return new Result<>().error("医院ID不存在");
        }
        //查询代理商
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(venderDevicePO.getAgent());
        if (sysUser == null || sysUser.getUserType() != 2) {
            return new Result<>().error("代理商不存");
        }
        VenderDeviceQueryVO venderDeviceQueryVO = new VenderDeviceQueryVO();
        VenderDevice venderDevice = new VenderDevice();
        venderDevice.setDeviceSn(venderDevicePO.getDeviceSn());
        List<VenderDevice> venderDevices = venderDeviceMapper.selectByCondition(venderDevice);
        if (venderDevices == null || venderDevices.size() == 0) {
            BeanUtils.copyProperties(venderDevicePO, venderDevice);
            Date time = new Date();
            venderDevice.setCreateTime(time);
            venderDevice.setDeviceStatus(2); //设备状态：1：未激活，2：已激活使用中(启用):3：已禁用 4 故障',
            venderDevice.setUpdateTime(time);
            venderDevice.setUpdated(venderDevice.getCreated());
            venderDeviceMapper.insertSelective(venderDevice);
            //新增变更记录
            DeviceChangeRecord changeRecord = new DeviceChangeRecord();
            changeRecord.setDeviceId(venderDevice.getId());
            changeRecord.setDeviceSn(venderDevice.getDeviceSn());
            changeRecord.setEventType(DeviceChangeEventTypeEnum.NEW_CREATE.eventType);
            changeRecord.setEventDesc(DeviceChangeEventTypeEnum.NEW_CREATE.eventDes);
            changeRecord.setChangeTime(time);
            LoginData currentUser = SessionUtil.getCurrentUser();
            changeRecord.setOperator(currentUser.getUserId());
            changeRecord.setOperatorName(currentUser.getUsername());
            changeRecord.setCreateTime(time);
            changeRecordMapper.insert(changeRecord);
            BeanUtils.copyProperties(venderDevice, venderDeviceQueryVO);
            List<DeviceBox> deviceBoxes = new ArrayList<>();
            for (int i = 1; i <= 8; i++) {
                DeviceBox deviceBox = new DeviceBox();
                deviceBox.setDeviceId(venderDevice.getId());
                deviceBox.setBoxType(1);
                deviceBox.setBoxNum(String.valueOf(i));
                deviceBox.setLockStatus(2);
                deviceBoxMapper.insertSelective(deviceBox);
                deviceBoxes.add(deviceBox);
            }
            for (int i = 1; i <= 4; i++) {
                DeviceBox deviceBox = new DeviceBox();
                deviceBox.setDeviceId(venderDevice.getId());
                deviceBox.setBoxType(2);
                deviceBox.setBoxNum(String.valueOf(i));
                deviceBox.setLockStatus(2);
                deviceBoxMapper.insertSelective(deviceBox);
                deviceBoxes.add(deviceBox);
            }
            venderDeviceQueryVO.setDeviceBoxes(deviceBoxes);
            return new Result<VenderDeviceQueryVO>().ok(venderDeviceQueryVO);
        } else {
            return new Result<>().error("设备编号：" + venderDevice.getDeviceSn() + "已经存在");
        }
    }

    @Override
    public Result<Boolean> removeById(Long id) {
        venderDeviceMapper.deleteByPrimaryKey(id);
        return new Result<>().ok();
    }

    @Override
    public Result<Boolean> modifyById(VenderDeviceModifyPO venderDeviceModifyPO) {
        Long id = venderDeviceModifyPO.getId();
        VenderDevice venderDevice = new VenderDevice();
        //新增变更记录
        DeviceChangeRecord changeRecord = new DeviceChangeRecord();
        VenderDevice old = venderDeviceMapper.selectByPrimaryKey(venderDeviceModifyPO.getId());
        if (ObjectUtils.isEmpty(old)) {
            throw new BusinessException("当前记录不存在");
        }
        Boolean changed = judgeAddrChange(old, venderDeviceModifyPO);
        //判断变更内容
        if (!old.getHospitalId().equals(venderDeviceModifyPO.getHospitalId()) && changed) {
            changeRecord.setEventType(DeviceChangeEventTypeEnum.CHANGE_HOSPITAL_ADDR.eventType);
            changeRecord.setEventDesc(DeviceChangeEventTypeEnum.CHANGE_HOSPITAL_ADDR.eventDes);
        } else if (!old.getHospitalId().equals(venderDeviceModifyPO.getHospitalId())) {
            changeRecord.setEventType(DeviceChangeEventTypeEnum.CHANGE_HOSPITAL.eventType);
            changeRecord.setEventDesc(DeviceChangeEventTypeEnum.CHANGE_HOSPITAL.eventDes);
        } else if (changed) {
            changeRecord.setEventType(DeviceChangeEventTypeEnum.CHANGE_ADDR.eventType);
            changeRecord.setEventDesc(DeviceChangeEventTypeEnum.CHANGE_ADDR.eventDes);
        } else {
            changeRecord.setEventType(DeviceChangeEventTypeEnum.CHANGE_ADDR.eventType);
            changeRecord.setEventDesc(DeviceChangeEventTypeEnum.CHANGE_ADDR.eventDes);
        }
        System.out.println("=============");
        System.out.println(venderDeviceModifyPO);
        BeanUtils.copyProperties(venderDeviceModifyPO, venderDevice);
        Date time = new Date();
        venderDevice.setUpdateTime(time);
        System.out.println(venderDevice);
        venderDeviceMapper.updateByPrimaryKeySelective(venderDevice);
        changeRecord.setDeviceId(old.getId());
        changeRecord.setDeviceSn(old.getDeviceSn());
        changeRecord.setOldInfo(JSONObject.toJSONString(old));
        changeRecord.setNewInfo(JSONObject.toJSONString(venderDeviceModifyPO));
        LoginData currentUser = SessionUtil.getCurrentUser();
        changeRecord.setOperator(currentUser.getUserId());
        changeRecord.setOperatorName(currentUser.getUsername());
        changeRecord.setChangeTime(time);
        changeRecord.setCreateTime(time);
        changeRecordMapper.insert(changeRecord);
        return new Result<Boolean>().ok(true);
    }

    private Boolean judgeAddrChange(VenderDevice old, VenderDeviceModifyPO venderDeviceModifyPO) {
        Boolean changed = true;
        if (old.getProvinceName() != null && old.getProvinceName().equals(venderDeviceModifyPO.getProvinceName())
                &&
                (old.getCityName() != null && old.getCityName().equals(venderDeviceModifyPO.getCityName()))
                &&
                (old.getCountyName() != null && old.getCountyName().equals(venderDeviceModifyPO.getCountyName()))
                &&
                (old.getStreetName() != null && old.getStreetName().equals(venderDeviceModifyPO.getStreetName()))
                &&
                (old.getDetailAddress() != null && old.getDetailAddress().equals(venderDeviceModifyPO.getDetailAddress()))) {
            changed = false;
        }
        return changed;
    }

    @Override
    public Result<VenderDeviceQueryVO> queryById(Long id) {
        VenderDeviceQueryVO venderDeviceQueryVO = new VenderDeviceQueryVO();
        VenderDevice venderDevice = venderDeviceMapper.selectByPrimaryKey(id);
        if (venderDevice == null) {
            return new Result<>().ok();
        } else {
            BeanUtils.copyProperties(venderDevice, venderDeviceQueryVO);
            venderDeviceQueryVO.setDeviceNumber(org.apache.commons.lang.StringUtils.leftPad(String.valueOf(venderDeviceQueryVO.getId()), 6, "0"));

            //关联广告
            if (!StringUtils.isEmpty(venderDevice.getHospitalId())) {
                PlacedHospital placedHospital = placedHospitalMapper.selectByPrimaryKey(venderDevice.getHospitalId());
                if (placedHospital != null && !StringUtils.isEmpty(placedHospital.getAdvertisementId())) {
                    Advertisement advertisement = advertisementMapper.selectByPrimaryKey(placedHospital.getAdvertisementId());
                    venderDeviceQueryVO.setAdvertisement(advertisement);
                }
            }
            //关联box
            List<DeviceBox> deviceBoxes = deviceBoxMapper.selectByDeviceId(id);
            venderDeviceQueryVO.setDeviceBoxes(deviceBoxes);
            List<DeviceChangeRecord> changeRecordList = changeRecordMapper.selectChangeRecordListByDeviceId(id);
            venderDeviceQueryVO.setChangeRecordList(changeRecordList);
            //
            AppVersionUpgrade appVersionUpgrade = appVersionUpgradeMapper.selectByApkName(venderDevice.getAppVersion());
            if (!ObjectUtils.isEmpty(appVersionUpgrade)) {
                venderDeviceQueryVO.setAppVersionTitle(appVersionUpgrade.getTitle());
            }

        }
        return new Result<VenderDeviceQueryVO>().ok(venderDeviceQueryVO);
    }

    @Override
    public Result<GenericPage<VenderDeviceVO>> queryAll(VenderDeviceQueryPO venderDeviceQueryPO) {

        int pageNo = venderDeviceQueryPO.getPageNo() == 0 ? 1 : venderDeviceQueryPO.getPageNo();
        int pageSize = venderDeviceQueryPO.getPageSize() == 0 ? 10 : venderDeviceQueryPO.getPageSize();
//        PageHelper.startPage(pageNo, pageSize);

        List<VenderDeviceVO> list = new ArrayList<>();

        PageInfo<VenderDeviceVO> pageInfo = PageHelper.startPage(pageNo, pageSize).doSelectPageInfo(() -> {

            VenderDevice venderDevice = new VenderDevice();
            Long businessId = CurrentLoginUserAgent.getBusinessId();

            BeanUtils.copyProperties(venderDeviceQueryPO, venderDevice);

            if (ObjectUtils.isEmpty(venderDevice.getAgent())){
                venderDevice.setAgent(businessId);
            }
//        List<VenderDevice> venderDevices = venderDeviceMapper.selectByCondition(venderDevice);

            List<VenderDevice> venderDevices = venderDeviceMapper.selectByAgent(venderDevice.getAgent(),venderDeviceQueryPO.getDeviceSn(),venderDevice.getHospitalId());

            VenderDeviceVO vo = null;
            for (VenderDevice device : venderDevices) {
                vo = new VenderDeviceVO();
                BeanUtils.copyProperties(device, vo);
                vo.setDeviceNumber(org.apache.commons.lang.StringUtils.leftPad(String.valueOf(vo.getId()), 6, "0"));
                int i = deviceBoxMapper.countNoStock(vo.getId());
                vo.setEmptyCount(i);
                AppVersionUpgrade appVersionUpgrade = appVersionUpgradeMapper.selectByApkName(device.getAppVersion());
                if (!ObjectUtils.isEmpty(appVersionUpgrade)) {
                    vo.setAppVersionTitle(appVersionUpgrade.getTitle());
                }

                //填充变更记录
                List<DeviceChangeRecord> changeRecordList = changeRecordMapper.selectChangeRecordListByDeviceId(device.getId());
                vo.setChangeRecordList(changeRecordList);
                list.add(vo);

                PlacedHospital placedHospital = placedHospitalMapper.selectByPrimaryKey(device.getHospitalId());
                if (!ObjectUtils.isEmpty(placedHospital)){
                    vo.setHospitalName(placedHospital.getHospitalName());
                }
            }
        });


//        PageInfo<VenderDeviceVO> pageInfo = new PageInfo<>(list);
        GenericPage<VenderDeviceVO> genericPage = new GenericPage<>(pageSize, pageInfo.getTotal(), list);
        return new Result<GenericPage<VenderDeviceVO>>().ok(genericPage);
    }


    public Result<DeviceInfoVO> queryDeviceDetailInfoBySn(String sn) {
        VenderDevice device = new VenderDevice();
        device.setDeviceSn(sn);
        List<VenderDevice> venderDevices = venderDeviceMapper.selectByCondition(device);
        if (venderDevices == null || venderDevices.size() == 0) {
            return new Result<>().ok();
        } else {
            device = venderDevices.get(0);
            DeviceInfoVO deviceInfoVO = new DeviceInfoVO();
            VenderDeviceQueryVO vo = new VenderDeviceQueryVO();
            BeanUtils.copyProperties(venderDevices.get(0), vo);
            vo.setDeviceNumber(org.apache.commons.lang.StringUtils.leftPad(String.valueOf(vo.getId()), 6, "0"));
            deviceInfoVO.setDevice(vo);
            if (!StringUtils.isEmpty(device.getHospitalId())) {
                PlacedHospital placedHospital = placedHospitalMapper.selectByPrimaryKey(device.getHospitalId());
                deviceInfoVO.setPlacedHospital(placedHospital);
            }
            return new Result<DeviceInfoVO>().ok(deviceInfoVO);
        }
    }

    public Result<DeviceInfoVO> queryDeviceDetailInfoBySnAndHandleAppVersion(String sn, String appVersion) {
        VenderDevice device = new VenderDevice();
        device.setDeviceSn(sn);
        List<VenderDevice> venderDevices = venderDeviceMapper.selectByCondition(device);
        if (venderDevices == null || venderDevices.size() == 0) {
            return new Result<>().ok();
        } else {
            device = venderDevices.get(0);
            //更新设备的应用版本
            device.setAppVersion(appVersion);
            venderDeviceMapper.updateByPrimaryKeySelective(device);

            DeviceInfoVO deviceInfoVO = new DeviceInfoVO();
            VenderDeviceQueryVO vo = new VenderDeviceQueryVO();
            BeanUtils.copyProperties(venderDevices.get(0), vo);
            vo.setDeviceNumber(org.apache.commons.lang.StringUtils.leftPad(String.valueOf(vo.getId()), 6, "0"));
            deviceInfoVO.setDevice(vo);
            if (!StringUtils.isEmpty(device.getHospitalId())) {
                PlacedHospital placedHospital = placedHospitalMapper.selectByPrimaryKey(device.getHospitalId());
                deviceInfoVO.setPlacedHospital(placedHospital);
            }
            return new Result<DeviceInfoVO>().ok(deviceInfoVO);
        }
    }

    @Override
    public Result<List<VenderDeviceVO>> getMineDevieList() {
        Long businessId = CurrentLoginUserAgent.getBusinessId();
        Result<List<VenderDeviceVO>> result = new Result<List<VenderDeviceVO>>();
        List<VenderDeviceVO> voList = Lists.newArrayList();
        VenderDevice condition = new VenderDevice();
        condition.setAgent(businessId);
        List<VenderDevice> deviceList = venderDeviceMapper.selectByCondition(condition);
        if (!ObjectUtils.isEmpty(deviceList)) {
            for (VenderDevice device : deviceList) {
                VenderDeviceVO vo = new VenderDeviceVO();
                BeanUtils.copyProperties(device, vo);
            }
        }
        return result.ok(voList);
    }
}
